package avicit.bdp.oss.utils.stats;

import avicit.bdp.oss.utils.common.Constants;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2020-11-12
 * @类说明：MathUtils
 * @修改记录：
 * @注意事项：
 * @主要功能：提供大数计算能力
 */
public class MathUtils {
    /**
     * 提供精确的加法运算。
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    public static String bigDecimalAdd(String value1, String value2) {
        BigDecimal b1 = new BigDecimal(value1);
        BigDecimal b2 = new BigDecimal(value2);
        return b1.add(b2).toString();
    }

    /**
     * 提供大数加法
     * @param value1 被加数
     * @param value2 加数
     * @return 两个参数的和
     */
    public static String bigIntegerAdd(String value1, String value2) {
        BigInteger b1 = new BigInteger(value1);
        BigInteger b2 = new BigInteger(value2);

        return b1.add(b2).toString();
    }

    /**
     * 提供大数自增长
     * @param value
     * @return
     */
    public static String incBigInteger(String value) {
        BigInteger b1 = new BigInteger(value);
        BigInteger b2 = new BigInteger("1");

        return b1.add(b2).toString();
    }

    /**
     * 提供大数减法
     * @param value1
     * @param value2
     * @return
     */
    public static String bigIntegerSubtract(String value1, String value2) {
        BigInteger b1 = new BigInteger(value1);
        BigInteger b2 = new BigInteger(value2);

        return b1.subtract(b2).toString();
    }

    /**
     * 提供大数自减1
     * @param value
     * @return
     */
    public static String decBigInteger(String value) {
        BigInteger b1 = new BigInteger(value);
        BigInteger b2 = new BigInteger("1");

        return b1.subtract(b2).toString();
    }

    /**
     * 存储单位处理，根据数值转为为合适的单位（B/KB/MB/GB/TB）
     * @param value
     * @return
     */
    public static Capacity storageUnitProcess(long value) {
        Capacity retValue = null;
        double tmpRet = 0.0;
        if (value <= Constants.KB) {
            // 小于1KB时，单位为B
            retValue = new Capacity(value, Constants.BYTE_UNIT);
        } else if (value > Constants.KB && value <= Constants.MB) {
            // 大于1KB and 小于1MB时，单位为KB
            tmpRet = (double) value / Constants.KB;
            retValue = new Capacity(tmpRet, Constants.KB_UNIT);
        } else if (value > Constants.MB && value <= Constants.GB) {
            // 大于1MB and 小于1GB时，单位为MB
            tmpRet = (double) value / Constants.MB;
            retValue = new Capacity(tmpRet, Constants.MB_UNIT);
        } else if (value > Constants.GB && value <= Constants.TB) {
            // 大于1MB and 小于1GB时，单位为GB
            tmpRet = (double) value / Constants.GB;
            retValue = new Capacity(tmpRet, Constants.GB_UNIT);
        } else {
            // 大于1TB时，单位为TB
            tmpRet = (double) value / Constants.TB;
            retValue = new Capacity(tmpRet, Constants.TB_UNIT);
        }

        // double类型数据格式化，仅保留两位有效数字，四舍五入
        DecimalFormat decimalFormat = new DecimalFormat(Constants.DATA_FORMAT);
        retValue.setCapacity(Double.parseDouble(decimalFormat.format(retValue.getCapacity())));

        return retValue;
    }

    /**
     * 存储单位处理，根据数值转为为合适的单位（B/KB/MB/GB/TB）
     * @param value
     * @return
     */
    public static TrafficPara storageUnitProcess2(long value) {
        TrafficPara retValue = null;
        double tmpRet = 0.0;
        if (value <= Constants.KB) {
            // 小于1KB时，单位为B
            retValue = new TrafficPara(0L, value, Constants.BYTE_UNIT);
        } else if (value > Constants.KB && value <= Constants.MB) {
            // 大于1KB and 小于1MB时，单位为KB
            tmpRet = (double) value / Constants.KB;
            retValue = new TrafficPara(0L, tmpRet, Constants.KB_UNIT);
        } else if (value > Constants.MB && value <= Constants.GB) {
            // 大于1MB and 小于1GB时，单位为MB
            tmpRet = (double) value / Constants.MB;
            retValue = new TrafficPara(0L, tmpRet, Constants.MB_UNIT);
        } else if (value > Constants.GB && value <= Constants.TB) {
            // 大于1MB and 小于1GB时，单位为GB
            tmpRet = (double) value / Constants.GB;
            retValue = new TrafficPara(0L, tmpRet, Constants.GB_UNIT);
        } else {
            // 大于1TB时，单位为TB
            tmpRet = (double) value / Constants.TB;
            retValue = new TrafficPara(0L, tmpRet, Constants.TB_UNIT);
        }

        // double类型数据格式化，仅保留两位有效数字，四舍五入
        DecimalFormat decimalFormat = new DecimalFormat(Constants.DATA_FORMAT);
        retValue.setMeasuredValue(Double.parseDouble(decimalFormat.format(retValue.getMeasuredValue())));

        return retValue;
    }

    /**
     * 计算var2相对月var1的增加比例，保留两位小数
     * @param var1
     * @param var2
     * @return
     */
    public static String calRatio(long var1, long var2) {
        // 二者相等，增减0%
        if (var1 == var2) {
            return "0.00%";
        }

        // 前者为0L，默认增加100%
        if (var1 == 0L) {
            return "100.00%";
        }

        DecimalFormat decimalFormat = new DecimalFormat(Constants.PERCENT_FORMAT);
        double retVar = (double)(var2 - var1) / (double)var1;

        return decimalFormat.format(retVar);
    }
}
